# -*- encoding: utf-8 -*-
#import odoo.addons.decimal_precision as dp
from odoo import models, fields, api, _
from odoo.addons import base_cw
from odoo.exceptions import  UserError
from odoo.tools.float_utils import float_round, float_compare


class AccountVoucherScript(models.Model):
    _name = 'account.voucher.script'
    _auto = 'False'
    _description = u'预切凭证基类'

    def _compute_is_generate_voucher_line(self):
        for master in self:
            master.is_generated_script_line = master.script_line_ids

    def _compute_is_voucher_line(self):
        for master in self:
            master.is_generated_voucher_line = master.voucher_id and master.voucher_id.line_ids and master.voucher_id.state not in (
            'cancel',)

    voucher_id = fields.Many2one('account.voucher', u'凭证编号', ondelete="restrict")
    is_generated_script_line = fields.Boolean(u'已生成预切明细', compute='_compute_is_generate_voucher_line')
    is_generated_voucher_line = fields.Boolean(u'已生成凭证明细', compute='_compute_is_voucher_line')

    # 需要在继承对象里重写该方法
    def _assert_balanced(self):
        # if not self.ids:
        #     return True
        # prec = self.env['decimal.precision'].precision_get('Amount')
        # self._cr.execute("""
        #         SELECT  master_id
        #           FROM  account_voucher_line
        #          WHERE  master_id in %s
        #       GROUP BY  master_id
        #         HAVING  abs(sum(debit) - sum(credit)) > %s
        #     """, (tuple(self.ids), 10 ** (-max(5, prec))))
        # if len(self._cr.fetchall()) != 0:
        #     raise UserError(_(u"预切凭证借贷不平，请检查."))
        raise UserError(_(u"请在继承模块里重写该方法."))
        # return True

    @api.model
    def _data_check(self):
        res = self._assert_balanced()
        prec = self.env['decimal.precision'].precision_get('Amount')
        if (float_compare(sum(self.script_line_ids.mapped('debit')) - sum(self.script_line_ids.mapped('credit')), 0.0,
                          precision_rounding=10 ** (-max(5, prec))) != 0
            or float_compare(
                    sum(self.script_line_ids.mapped('lc_debit')) - sum(self.script_line_ids.mapped('lc_debit')), 0.0,
                precision_rounding=10 ** (-max(5, prec))) != 0):
            raise UserError(_(u'借贷方金额不等,请确认!'))
        results = self.script_line_ids.filtered(lambda x: x.sub_account_type == 'has' and not x.sub_account_lines)
        for x in results:
            raise UserError(_(u'%s 为有辅助核算会科 但没有填写 辅助核算,请确认!' % (x.account_id.code + x.account_id.name)))
        return res

    def generate_account_voucher(self):
        """
        成生会计凭证
        :return:
        """
        self.ensure_one()
        self._data_check()
        if self.voucher_id:
            self.voucher_id.state = 'draft'
            self.voucher_id.line_ids.unlink()
        else:
            self.voucher_id = self.env['account.voucher'].create(dict(date=fields.Date.context_today(self),
                                                                      origin=self.name,
                                                                      voucher_category_id=self.env.ref(
                                                                          'cncw_ledger.account_voucher_category_09').id
                                                                      ))
        items = []
        for x in self.script_line_ids:
            item = dict(sequence=x.sequence,
                        dc_type=x.dc_type,
                        account_id=x.account_id.id,
                        sub_account_id=x.sub_account_id and x.sub_account_id.id or False,
                        sub_account_lines=[(6, 0, x.sub_account_lines.ids)],
                        name=x.name,
                        currency_id=x.currency_id and x.currency_id.id or False,
                        exchange_rate=x.exchange_rate,
                        debit=x.debit or False,
                        credit=x.credit or False,
                        lc_debit=x.lc_debit,
                        lc_credit=x.lc_credit,
                        company_id=x.company_id and x.company_id.id or False,
                        )
            items.append((0, 0, item))
        self.voucher_id.write(dict(line_ids=items))
        self._cr.commit()

    def generate_account_voucher_script_line(self):
        """
        产生预切凭证明细
        :return:
        """
        self.ensure_one()
        pass


class AccountVoucherScriptLine(models.Model):
    _name = 'account.voucher.script.line'
    _description = u'预切凭证明细'
    _order = 'sequence'

    @api.depends('account_id')
    def _get_sub_account_ids(self):
        account_obj = self.env['cncw.account']
        self.sub_account_ids = account_obj.get_sub_account_ids(self.account_id)



    def compute_sub_account_lines_str(self):
        for record in self:
            sub_account_lines_str = ''
            for line in record.sub_account_lines.filtered(lambda r: r.sub_account_id):
                sub_account_lines_str += ' | ' + line.sub_account_id.name
                if line.category_id.code == 'cash_flow':
                    record.sub_account_id = line.sub_account_id
            record.sub_account_lines_str = sub_account_lines_str

    # 预切凭证基类为虚类,不应该有字段去指向该类
    master_id = fields.Many2one('account.voucher.script', u'预切凭证基类', ondelete="cascade")
    invoice_id = fields.Many2one('cncw.invoice.move', u'发票', ondelete="cascade")

    ap_id = fields.Many2one('account.pay', u'付款单', ondelete="cascade")
    ar_id = fields.Many2one('account.receive', u'收款单', ondelete="cascade")

    sequence = fields.Integer(u'项次', default=1)
    dc_type = fields.Selection(base_cw.public.DC_TYPE, u'借贷', default='D', required=True)
    account_id = fields.Many2one('cncw.account', u'会计科目', required=True, ondelete="restrict")
    sub_account_id = fields.Many2one('res.partner', u'会计辅助核算', ondelete="restrict")
    sub_account_lines = fields.One2many('sub.account.line', 'script_line_id', string=u'会计辅助核算')
    sub_account_lines_str = fields.Char(string=u'会计辅助核算', compute='compute_sub_account_lines_str')
    sub_account_type = fields.Selection(base_cw.public.SUB_ACCOUNT_TYPE, u'辅助核算类型',
                                        related='account_id.sub_account_type')
    sub_account_ids = fields.Many2many('res.partner', compute='_get_sub_account_ids', string=u'可选辅助核算')
    name = fields.Char(u'摘要')
    currency_id = fields.Many2one('res.currency', u'币别', default=lambda self: self.env.user.company_id.currency_id)
    exchange_rate = fields.Float(u'汇率', digits='Exchange Rate', defualt=1.0)
    debit = fields.Float(u'借方金额', digits='Product Price',)
    credit = fields.Float(u'贷方金额', digits='Product Price',)

    lc_debit = fields.Float(u'本币借方金额', digits='Product Price',)
    lc_credit = fields.Float(u'本币贷方金额', digits='Product Price',)
    company_id = fields.Many2one('res.company', string=u'公司', change_default=True,
                                 required=True, readonly=True, states={'draft': [('readonly', False)]},
                                 default=lambda self: self.env.company)
    picking_id = fields.Many2one('stock.picking', string=u'调拨单')
    voucher_id = fields.Many2one('account.voucher', string=u'记账凭证')
    move_ids = fields.Many2many('stock.move', string=u'关联移动')
    voucher_template_id = fields.Many2one('account.voucher.template', string='凭证模板')

    # def compute_sub_account_lines_str(self):
    #     for record in self:
    #         sub_account_lines_str = ''
    #         for line in record.sub_account_lines.filtered(lambda r: r.sub_account_id):
    #             sub_account_lines_str += line.sub_account_id.name
    #         record.sub_account_lines_str = sub_account_lines_str

    def edit_sub_account_lines(self):
        return {
            "type": "ir.actions.act_window",
            "res_model": "account.voucher.script.line",
            'view_mode': 'form',
            'view_id': self.env.ref('cncw_ledger.view_account_voucher_script_line_form2').id,
            "res_id": self.id,
            "name": "编辑辅助核算",
            "target": 'new'
        }

    @api.model
    def create(self, vals):
        master_column = ''
        if vals.get('invoice_id', False):
            master_column = 'invoice_id'
        elif vals.get('adjust_id', False):
            master_column = 'adjust_id'
        elif vals.get('ap_id', False):
            master_column = 'ap_id'
        elif vals.get('ar_id', False):
            master_column = 'ar_id'
        elif vals.get('ar_bill_id', False):
            master_column = 'ar_bill_id'
        elif vals.get('ap_bill_id', False):
            master_column = 'ap_bill_id'
        base_cw.public.generate_sequence(self, vals, master_column=master_column)
        return super(AccountVoucherScriptLine, self).create(vals)
